﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading;
using ModEngine;
using System.Windows.Media.Imaging;
using System.IO;

namespace Iris.Engine
{

    public class SortCore : Core
    {

        public delegate void ImageSortArgHandler(ImageSort arg1);
        public delegate void ImageSortArg2Handler(ImageSort gagnant, ImageSort perdant);
        public delegate void DuelProgressionHandler(ImageSort imageA, ImageSort imageB, int progression);
        public delegate void ListOfImageSortArgHandler(List<ImageSort> list);
        public delegate void FileInfoArgHandler(FileInfo arg1);
        public delegate void StringProgressionArgsHandler(string s, int a, int b);
        public delegate void ImageSortProgressionArgsHandler(ImageSort arg1, int a, int b);
        
        #region events
        public event StringArgHandler       BeginLoadDataSourceEvent = delegate { };
        public event ImageSortProgressionArgsHandler WaitLoadDataSourceEvent = delegate { };
        public event ImageSortArgHandler    LoadDataSourceEvent = delegate { };
        public event FileInfoArgHandler     LoadDataSourceFailedEvent = delegate { };
        public event NoArgsHandler          EndLoadDataSourceEvent = delegate { };
        
        public event NoArgsHandler          BeginLoadDuelEvent = delegate { };
        public event DuelProgressionHandler LoadDuelEvent = delegate { };
        public event NoArgsHandler          LoadDuelAucuneImageEvent = delegate { };
        public event NoArgsHandler          LoadDuelPlusDeDuelEvent = delegate { };
        public event ImageSortArg2Handler   EndLoadDuelEvent = delegate { };
        public event ImageSortArg2Handler   EndLoadDuelNullEvent = delegate { };
        public event ImageSortArgHandler    BlameImageEvent = delegate { };
        public event ImageSortArgHandler    ActivateImageEvent = delegate { };
        

        public event ListOfImageSortArgHandler ImagesUpdatedEvent = delegate { };

        public event ListOfImageSortArgHandler BeginUpdateFiveStarEvent = delegate { };
        public event StringProgressionArgsHandler UpdateFiveStarEvent = delegate { };
        public event StringArgHandler UpdateFiveStarFailedEvent = delegate { };
        public event NoArgsHandler EndUpdateFiveStarEvent = delegate { };

        public event NoArgsHandler ExceptionSystemBusyEvent = delegate { };

        #endregion

        #region Invoke

        /// <summary>
        /// Le chargement des images est réclamé
        /// </summary>
        /// <param name="path">Chemin vers les images</param>
        public void BeginLoadDataSource(string path) {
            try {
                BeginLoadDataSourceEvent.Invoke(path);
            }
            catch (Exception e) {
                RaiseException(e, "BeginLoadDataSource");
            }
        }

        /// <summary>
        /// Le chargement des données est en cours
        /// </summary>
        /// <param name="arg1">Image en chargement</param>
        /// <param name="index">index de l'image en cours de chargement</param>
        /// <param name="total">Nombre image totale à charger</param>
        public void WaitLoadDataSource(ImageSort image, int index, int total) {
            try
            {
                WaitLoadDataSourceEvent.Invoke(image, index, total);
            }
            catch (Exception e) {
                RaiseException(e, "WaitLoadDataSource");
            }
        }

        /// <summary>
        /// chargement terminé pour l'image
        /// </summary>
        /// <param name="image">image chargé</param>
        public void LoadDataSource(ImageSort image) {
            try
            {
                LoadDataSourceEvent.Invoke(image);
            }
            catch (Exception e)
            {
                RaiseException(e, "LoadDataSource");
            }
        }

        /// <summary>
        /// Problème avec le chargement de images
        /// </summary>
        /// <param name="file">Fichier incriminé</param>
        public void LoadDataSourceFailed(FileInfo file) {
            try
            {
                LoadDataSourceFailedEvent.Invoke(file);
            }
            catch (Exception e) {
                RaiseException(e, "LoadDataSourceFailed");
            }
        }

        /// <summary>
        /// Chargement des toutes les images terminés
        /// </summary>
        public void EndLoadDataSource() {
            try
            {
                EndLoadDataSourceEvent.Invoke();
            }
            catch (Exception e){
                RaiseException(e, "EndLoadDataSource");
            }
        }

        /// <summary>
        /// Un duel est réclamé
        /// </summary>
        public void BeginLoadDuel() {
            try
            {
                BeginLoadDuelEvent.Invoke();
            }
            catch (Exception e) {
                RaiseException(e, "BeginLoadDuel");
            }
        }

        /// <summary>
        /// Un duel est soumi
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void LoadDuel(ImageSort a, ImageSort b, int progression) {
            try
            {
                LoadDuelEvent.Invoke(a, b, progression);
            }
            catch (Exception e){
                RaiseException(e, "LoadDuel");
            }
        }

        /// <summary>
        /// Impossible de soumettre un duel
        /// </summary>
        public void LoadDuelAucuneImage() {
            try
            {
                LoadDuelAucuneImageEvent.Invoke();
            }
            catch (Exception e) {
                RaiseException(e, "LoadDuelAucuneImage");
            }
        }

        /// <summary>
        /// Impossible de soumettre un duel
        /// </summary>
        public void LoadDuelPlusDeDuel() {
            try
            {
                LoadDuelPlusDeDuelEvent.Invoke();
            }
            catch (Exception e) {
                RaiseException(e, "LoadDuelPlusDeDuel");
            }
        }

        /// <summary>
        /// Résultat un duel déclaré
        /// </summary>
        /// <param name="gagnant"></param>
        /// <param name="perdant"></param>
        public void EndLoadDuel(ImageSort gagnant, ImageSort perdant) {
            try
            {
                EndLoadDuelEvent.Invoke(gagnant, perdant);
            }
            catch(Exception e)
            {
                RaiseException(e, "EndLoadDuel");
            }
        }

        /// <summary>
        /// Résultat d'un duel déclaré null
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public void EndLoadDuelNull(ImageSort a, ImageSort b) {
            try
            {
                EndLoadDuelNullEvent.Invoke(a, b);
            }
            catch (Exception e){
                RaiseException(e, "EndLoadDuelNull");
            }
        }


        public void BlameImage(ImageSort image) {
            try {
                BlameImageEvent.Invoke(image);
            }
            catch(Exception e) {
                RaiseException(e, "BlameImageEvent");
            }

        }
        
        public void ActivateImage(ImageSort image) {
            try {
                ActivateImageEvent.Invoke(image);
            }
            catch(Exception e) {
                RaiseException(e, "ActivateImageEvent");
            }
        }


        /// <summary>
        /// Signal au tiers que les données des images sont modifiés.
        /// </summary>
        /// <param name="images"></param>
        public void ImagesUpdated(List<ImageSort> images)
        {
            try
            {
                ImagesUpdatedEvent.Invoke(images);
            }
            catch (Exception e)
            {
                RaiseException(e, "ImagesUpdated");
            }
        }

        public void BeginUpdateFiveStar(List<ImageSort> images)
        {
            try
            {
                BeginUpdateFiveStarEvent.Invoke(images);
            }
            catch (Exception e)
            {
                RaiseException(e, "BeginUpdateFiveStar");
            }
        }

        #endregion

        #region singleton
        private static SortCore _singleton;
        static public SortCore singleton {get{
            if (_singleton ==null) _singleton = new SortCore();
            return _singleton;}
        }
        #endregion

        public void UpdateFiveStar(string message, int index, int total)
        {
            try
            {
                UpdateFiveStarEvent.Invoke(message, index, total);
            }
            catch (Exception e)
            {
                RaiseException(e, "UpdateFiveStar");
            }
        }

        public void UpdateFiveStarFailed(string message)
        {
            try
            {
                UpdateFiveStarFailedEvent.Invoke(message);
            }
            catch (Exception e)
            {
                RaiseException(e, "UpdateFiveStarFailedEvent");
            }
        }
    }
}
